# -*- coding:utf8 -*-
import json
import re
import typing
import requests
import traceback
from scrapy import Request
from .china_marathon import ChinaMarathon
from squirrel_core.commons.utils.get_config import get_config
from squirrel_core.frame.spider_makaka import MakakaSpider


class malasong_user(MakakaSpider):
    name = "malasong_user"
    start_url = "https://www.runchina.org.cn/"
    header = {
        "Content-Type": "application/json"
    }
    serialNumber = ""
    base_config = get_config(sections="base")
    ssdb_host = base_config.get('ssdb_host')
    ssdb_port = base_config.get('ssdb_port')

    def get_ext_requests_or_urls(self, data=None):
        if data and isinstance(data, str):
            data = json.loads(data)
        if data and isinstance(data, typing.MutableMapping):
            self.serialNumber = data.get("serialNumber", "")
            user_name = data.get("spider_config", {}).get("user_name", "")
            card_num = data.get("spider_config", {}).get("card_num", "")
            home_url = data.get("spider_config", {}).get("url", "")
            if not all([user_name, card_num]):
                self.logger.info("参数不全，请仔细核对")
                self.upload_procedure({"serialNumber": self.serialNumber, "code": 101, "message": "参数不全，请仔细核对"})
                self.close_after_idle = True
                self.force_to_close_spider = True
            else:
                self.upload_procedure({"serialNumber": self.serialNumber, "code": 100, "message": "任务启动成功"})
                use_proxy = data.get("spider_config", {}).get("use_proxy", True)
                if home_url and "timesToken" in home_url:
                    header = {
                        "Host": "api-changzheng.chinaath.com",
                        # "machineCode": "a398c22fac18911e2736b91ffb69c4de",
                        "Accept": "application/json, text/plain, */*",
                        "Content-Type": "application/json",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"
                    }
                    token = "".join(re.findall(r"timesToken=(.*)", home_url)).strip()
                    data = {"timesToken": token, "cardNo": card_num, "competitionName": "", "offlineScoreType": None,
                            "userName": user_name, "pageNo": 1, "pageQueryFlag": False, "pageSize": 9999}
                    url = "https://api-changzheng.chinaath.com/changzheng-score-center-api/api/app/score/offline/mineRaceScoreWithToken"
                    yield Request(url=url, callback=self.parse_score, dont_filter=True, method="POST",
                                  errback=self.err_parse, headers=header, body=json.dumps(data),
                                  meta={"user_name": user_name})
                else:
                    yield Request(url=self.start_url, callback=self.parse, dont_filter=True,
                                  errback=self.err_parse,headers=self.header,
                                  meta={"user_name": user_name, "card_num": card_num, "use_proxy": use_proxy, "handle_httpstatus_list": [302]})

    def parse(self, response, **kwargs):
        user_name = response.meta.get("user_name", "")
        card_num = response.meta.get("card_num", "")
        proxy_url = response.request.meta.get("proxy", "")
        proxy_pre = response.request.meta.get("proxy_pre", "")
        try:
            i = 0
            score_data = ''
            while i < 3:
                self.logger.info(f"开始第{i+1}次请求{user_name}的成绩信息")
                try:
                    score_data = ChinaMarathon().get_core(self.serialNumber, user_name, card_num, proxy_url, proxy_pre, self.logger)
                    if not score_data:
                        proxy_url = self.get_proxy() if self.use_proxy else ""
                    else:
                        break
                except Exception as e:
                    self.logger.info(f"处理{user_name}成绩时失败:{e}")
                    proxy_url = self.get_proxy() if self.use_proxy else ""
                i += 1
            if score_data:
                try:
                    if isinstance(score_data, dict):
                        count = len(score_data.get("data", {}).get("results", []))
                    else:
                        count = len(json.loads(score_data).get("data", {}).get("results", []))
                    self.logger.info(f"获取{user_name}的成绩成功,共{count}条记录")
                except:
                    self.logger.info(f"获取{user_name}的成绩成功")
                _data = str(score_data)
            else:
                self.logger.info(f"获取{user_name}的成绩失败：{score_data}")
                _data = str({"msg": "采集失败，请重试"})
            result_dict = {"serialNumber": self.serialNumber, "webType": self.name_first,
                           "crawlerType": self.name_second, "data": _data}
            result = self.result_item_assembler(response)
            result['result_data'] = result_dict
            yield result
        except Exception:
            self.logger.error(f"请求{user_name}的成绩信息：{traceback.format_exc()}")

    def parse_score(self, response, **kwargs):
        user_name = response.meta.get("user_name", "")
        try:
            self.logger.info(f"开始请求{user_name}的成绩信息")
            score_data = response.text
            if score_data and "凭证已失效" not in score_data:
                self.logger.info("获取成绩成功")
                _data = score_data
            else:
                self.logger.info(f"获取{user_name}的成绩失败：{score_data}")
                _data = str({"msg": "查询凭证已失效，请重试"})
            result_dict = {"serialNumber": self.serialNumber, "webType": self.name_first,
                           "crawlerType": self.name_second, "data": _data}
            result = self.result_item_assembler(response)
            result['result_data'] = result_dict
            yield result
        except Exception:
            self.logger.error(f"请求{user_name}的成绩信息：{traceback.format_exc()}")

    def get_proxy(self):
        while True:
            proxy = ""
            url = "http://ho09cytu.user.xiecaiyun.com/api/proxies?action=getJSON&key=NP047FE78B&count=1&word=&rand=true&norepeat=false&detail=true&ltime=&idshow=true"
            content = json.loads(requests.get(url).text).get("result", [])
            if content:
                ip = content[0].get("ip", "")
                port = content[0].get("port", "")
                proxy = f"http://{ip}:{port}"
                break
        return proxy

    def err_parse(self, failure):
        self.logger.warning(f"请求失败：{failure.request.url},错误原因:{traceback.format_exc()}")
